<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    <script>
        // 2. 为何需要收集依赖
        // 如何收集？
        // 把依赖收集的代码抽离出来封装到dep类
        /**
         * 新增依赖
         * 删除依赖
         * 向依赖发送通知
         * **/
        class Dep {
            constructor () {
                this.subs = []
            }
            addSub (sub) {
                this.subs.push(sub)
            }
            removeSub (sub) {
                remove(this.subs, sub)
            }
            depend (sub) {
                if (window.target) {
                    this.addSub(window.target)
                }
            }
            notify (subs) {
                // 通知依赖执行
                for (let i = 0; i < subs.length; i++) {
                    subs[i].update()
                }
            }
        }

        // 移除函数
        function remove (array, item) {
            if (array.length) {
                let index = array.indexOf(item)
                if (index > -1) {
                    array.splice(index, 1)
                }
            }
        }

        // 改造该函数
        function defineReactive (data, key, val) {
            let dep = new Dep()
            Object.defineProperty(data, key, {
                enumerable: true,
                configurable: true,
                get: function () {
                    // 存储依赖
                    dep.depend()
                    return val
                },
                set: function (newVal) {
                    if (val === newVal) {
                        return
                    }
                    // 通知依赖
                    dep.notify()
                    val = newVal
                }
            })
        }
        let xhg = {
            height: 180
        }
        defineReactive(xhg, 'height', 190)
        console.log(xhg.height, 'xhg.height');
    </script>
</body>
</html>
